package goo

import (
	"github.com/roseboy/goo/utils"
	"log"
	"net/http"
	"strings"
)

//route handle
func handle(response http.ResponseWriter, request *http.Request) {
	url := request.Method + ":" + strings.TrimRight(request.URL.Path, "/")
	log.Println("request==>" + url)
	handle, pattern, values, ok := routeHandleMatch(url)
	if !ok {
		page404Handle(response, request)
		return
	}
	ctx := &Context{Request: request, Writer: &response, attrValue: make(map[string]interface{}), requestValue: values}
	interceptors := InterceptorInstance().GetInterceptors(pattern)
	if interceptors == nil || len(interceptors) == 0 {
		handle(ctx)
	} else {
		invocations := make([]*Invocation, len(interceptors)+1)
		inv := &Invocation{Ctx: ctx, Handle: handle}
		invocations[len(interceptors)] = inv
		for i := len(interceptors) - 1; i >= 0; i-- {
			invocations[i] = &Invocation{Ctx: ctx, Interceptor: interceptors[i], invocation: invocations[i+1]}
		}
		invocations[0].Interceptor(invocations[0].invocation)
		invocations = nil
	}
}

func routeHandleMatch(route string) (func(*Context), string, map[string]string, bool) {
	urlValue := make(map[string]string)
	for _, pattern := range RoutesInstance().routePattern {
		isMatch := utils.AntPathMatcherInstance().DoMatch(pattern, route, urlValue)
		if isMatch {
			return RoutesInstance().routeFunc[pattern], pattern, urlValue, true
		}
	}
	return nil, "", nil, false
}

//静态文件处理
func staticHandle(ctx *Context) {
	url := ctx.Request.URL.Path
	for staticPrefix, staticDir := range ConfigInstance().StaticDir {
		staticPrefix = strings.ReplaceAll(staticPrefix, "*", "")
		staticPrefix = strings.TrimRight(staticPrefix, "/")
		if strings.HasPrefix(url, staticPrefix) {
			file := staticDir + url[len(staticPrefix):]
			//log.Println("request==>File:" + file)
			http.ServeFile(*ctx.Writer, ctx.Request, file)
			return
		}
	}
}

func page404Handle(response http.ResponseWriter, request *http.Request) {
	response.WriteHeader(404)
	response.Write([]byte("404 page not found"))
}
